<?php
/**
 * Created by PhpStorm.
 * User: ownfi
 * Date: 2017-04-13
 * Time: 20:28
 */

namespace App\Services\Impl;


use App\Common\Constant\Params;
use App\Events\MasterCashed;
use App\Events\MasterReturnFund;
use App\Models\HistorySystemBalance;
use App\Models\MasterCash;
use App\Models\MasterFund;
use App\Models\MasterTradeLog;
use App\Models\MerchantTradeLog;
use App\Services\IFinanceService;
use App\Services\IMasterLogService;
use App\Services\ISystemTaskService;
use App\Services\IWalletService;
use App\Services\Request;
use DB;
use Log;

class FinanceServiceImpl implements IFinanceService
{
    private $walletService;
    private $masterLogService;

    /**
     * FinanceServiceImpl constructor.
     */
    public function __construct(IWalletService $walletService,IMasterLogService $masterLogService)
    {
        $this->walletService = $walletService;
        $this->masterLogService = $masterLogService;
    }

    public function masterTradeList(array $wheres = [])
    {
        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
        ->whereIn('type',[Params::TRADE_TYPE_ORDER,Params::TRADE_TYPE_REFUND,Params::TRADE_TYPE_PUNISH]);
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function merchantTradeList(array $wheres = [])
    {
        $model = MerchantTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')->with(['merchant']);
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function masterFundTradeList(array $wheres = [])
    {
        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
        ->where('type',Params::TRADE_TYPE_ASSURE)->where('status',Params::TRADE_STATUS_SUCCESS)->with(['assoc']);
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function masterFundTradeReturningList(array $wheres = [])
    {
        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
            ->where('t1.type',Params::TRADE_TYPE_RETURN_ASSURE)->with(['assoc']);
        $model->join(MasterFund::table().' as f', function ($join){
            $join->on('t1.order_number', '=', 'f.id')
                ->where('f.status',Params::MASTER_FUND_WAITING)
                ->where('f.amount','<>',0);
        });
        if ($wheres){
            foreach ($wheres as $where){
                if ($where[0] == 'add_time'){
                    $model->where('t1.add_time',$where[1],$where[2]);
                }else{
                    $model->where([$where]);
                }
            }
        }
        return $model->paginate(config('common.perpage'));
    }

    public function masterFundTradeReturnedList(array $wheres = [])
    {
        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
            ->where('t1.type',Params::TRADE_TYPE_RETURN_ASSURE)->with(['assoc']);
        $model->join(MasterFund::table().' as f', function ($join){
            $join->on('t1.order_number', '=', 'f.id')
                ->where('f.status',Params::MASTER_FUND_PASS);
        });
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function masterCashReviewList(array $wheres = [])
    {
        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
            ->where('type',Params::TRADE_TYPE_CASH)->where('status',Params::TRADE_STATUS_WAITING)->with(['assoc']);
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function masterCashPassList(array $wheres = [])
    {
        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
            ->where('type',Params::TRADE_TYPE_CASH)->where('status',Params::TRADE_STATUS_SUCCESS)->with(['assoc']);
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function masterCashRefuseList(array $wheres = [])
    {
        $masterCrashIds = MasterCash::where('status',Params::MASTER_CASH_REFUSE)->select('order_number')->get()->pluck('order_number');

        $model = MasterTradeLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')
            ->where('type',Params::TRADE_TYPE_CASH)->where('status',Params::TRADE_STATUS_SUCCESS)->whereIn('order_serial_number',$masterCrashIds)->with(['assoc']);

        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function cashDisagree(MasterCash $cash)
    {
        $trade_log = MasterTradeLog::where(['type'=>Params::TRADE_TYPE_CASH,'order_number'=>$cash->id])->first();
        if (!$trade_log){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss trade log'));
            return false;
        }

        return $trade_log->update(['status'=>Params::TRADE_STATUS_FAIL])
            && $cash->update(['status'=>Params::MASTER_CASH_REFUSE])
            && $this->walletService->raiseBalance($trade_log->id,$cash->master_id,$cash->amount);

    }

    public function cashAgree($cash_id)
    {
        $trade_log = MasterTradeLog::where(['type'=>Params::TRADE_TYPE_CASH,'order_number'=>$cash_id])->first();
        if (!$trade_log){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss trade log'));
            return false;
        }
        $cashOrder = MasterCash::find($cash_id);
        if (!$cashOrder){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss cash'));
            return false;
        }
        if (empty($cashOrder->alipay_name) || empty($cashOrder->alipay_account)){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss alipay account'));
            return false;
        }

        return $trade_log->update(['status'=>Params::TRADE_STATUS_SUCCESS])
            && $cashOrder->update(['status'=>Params::MASTER_CASH_PASS])
            && event(new MasterCashed($cash_id));//提现转账事件

    }

    public function cashAgreeMutil(array $cash_ids)
    {
        $ret = true;
        foreach ($cash_ids as $cash_id){
            $ret = $ret && $this->cashAgree($cash_id);
        }
        return $ret;
    }

    public function returnFundDisagree(MasterFund $fund)
    {
        $trade_log = MasterTradeLog::where(['type'=>Params::TRADE_TYPE_RETURN_ASSURE,'order_number'=>$fund->id])->first();
        if (!$trade_log){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss trade log'));
            return false;
        }

        return $trade_log->update(['status'=>Params::TRADE_STATUS_FAIL])
            && $fund->update(['status'=>Params::MASTER_FUND_REFUSE])
            && $this->walletService->raiseAssureFund($trade_log->id,$fund->master_id,$fund->amount);
    }

    public function returnFundAgree($fund_id)
    {
        $trade_log = MasterTradeLog::where(['type'=>Params::TRADE_TYPE_RETURN_ASSURE,'order_number'=>$fund_id])->first();
        if (!$trade_log){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss trade log'));
            return false;
        }
        $fundOrder = MasterFund::find($fund_id);
        if (!$fundOrder){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss fund'));
            return false;
        }
//        if (empty($fundOrder->alipay_name) || empty($fundOrder->alipay_account)){
//            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'miss alipay account'));
//            return false;
//        }

        return $trade_log->update(['status'=>Params::TRADE_STATUS_SUCCESS])
            && $fundOrder->update(['status'=>Params::MASTER_FUND_PASS])
//            && event(new MasterReturnFund($fund_id));//质保金转账事件
        && resolve(ISystemTaskService::class)->AssureFundReturn($fund_id);
    }

    public function returnFundAgreeMutil(array $fund_ids)
    {
        $ret = true;
        foreach ($fund_ids as $fund_id){
            $ret = $ret && $this->returnFundAgree($fund_id);
        }
        return $ret;
    }

    public function systemWalletHistory(array $wheres = [])
    {
        $model = HistorySystemBalance::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC')->with(['assoc']);
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

}